import requests
import math
import pandas as pd
from to_QQemail import goto_email
from get_up_xh import get_near_xh
from time import sleep
from get_jj_back import get_max_back
from datetime import datetime, date

# 读取数据
jj_my = pd.read_excel(r'../Fund_form_files/jj_bd.xlsx', dtype={'基金代码': str, '基金名称': str})
jj_rc = pd.read_excel(r'../Fund_form_files/JJ_ETF.xlsx', dtype={'基金代码': str, '基金名称': str, '板块': str})
list_jz = []
list_time = []
gz = []
gzf = []
gz_time = []
now_date = datetime.now().strftime('%m月%d日')


def get_fund_data(fund_code, page_count=1):
    for page in range(1, page_count + 1):
        url = f"http://api.fund.eastmoney.com/f10/lsjz?fundCode={fund_code}&pageIndex={page}&pageSize=20"
        headers = {'Referer': 'http://fundf10.eastmoney.com', 'User-Agent': 'Mozilla/5.0'}
        try:
            r = requests.get(url, headers=headers, timeout=10)
            data = r.json()['Data']['LSJZList']
            for item in data:
                list_jz.append(float(item['DWJZ']))
                list_time.append(item['FSRQ'])
        except Exception as e:
            print(f"基金 {fund_code} 历史数据获取失败: {e}")
    try:
        gz_url = f"http://fundgz.1234567.com.cn/js/{fund_code}.js"
        gz_response = requests.get(gz_url, timeout=10)
        gz_data = gz_response.text
        gz.append(float(gz_data.split('gsz":"')[1].split('","')[0]))
        gzf.append(float(gz_data.split('gszzl":"')[1].split('","')[0]))  # 估算涨幅
        gz_time.append(gz_data.split('gztime":"')[1].split('"});')[0])
    except Exception as e:
        print(f"基金 {fund_code} 当日估值获取失败: {e}")


def init_all():
    gz.clear()
    gzf.clear()
    list_jz.clear()
    list_time.clear()
    gz_time.clear()


def to_cy():
    jj_code = jj_my['基金代码'].values
    jj_name = jj_my['基金名称'].values
    jj_type = jj_my['板块'].values
    jj_jun_ben = jj_my['平均成本'].values  # 持仓成本
    with open(f'分析log/{now_date}持仓分析报告', 'w', encoding='utf-8') as f:
        for code in range(len(jj_code)):
            okk = ''
            min_ok = ''
            get_fund_data(jj_code[code])
            jj_max_hc = get_max_back(jj_code[code], 12)
            # 指标计算----------------------------------------------------------------
            min5 = min(list_jz[:5])
            min20 = min(list_jz[:20])
            pass_ma5 = sum(list_jz[:5]) / 5  # 昨日ma5
            pass_ma20 = sum(list_jz[:20]) / 20  # 昨日ma20
            now_ma5 = (sum(list_jz[:4]) + gz[0]) / 5  # 今日估算ma5
            now_ma20 = (sum(list_jz[:19]) + gz[0]) / 20  # 今日估算ma0
            my_bz_c = math.sqrt(sum((x - pass_ma20) ** 2 for x in list_jz[:20]))  # 计算20日标准差(波动率)
            upper_band = pass_ma20 + 2 * my_bz_c  # 布林带上轨
            lower_band = pass_ma20 - 2 * my_bz_c  # 布林带下轨
            now_syl = (gz[0] - jj_jun_ben[code]) / jj_jun_ben[code] * 100
            if pass_ma5 <= pass_ma20 and now_ma5 > now_ma20 and gz[0] < upper_band:
                now_action = '🐦‍🔥金叉'
            elif pass_ma5 >= pass_ma20 and now_ma5 < now_ma20:
                now_action = '💀死叉'
            else:
                now_action = '🈚没信号'
            if gz[0] >= upper_band:
                okk = '⬆️'
            elif gz[0] <= lower_band:
                okk = '⬇️'
            if gz[0] <= min20:
                min_ok = '52双低'
            elif gz[0] <= min5:
                min_ok = '5日低'
            else:
                min_ok = '正常'
            print(f'正在分析{jj_name[code]}({jj_code[code]})')
            print(f'获取上一次信号....')
            my_xh = get_near_xh(code, jj_my)
            f.write(f'🔍{jj_name[code]}({jj_code[code]})\n')
            f.write(f'🍞板块：{jj_type[code]}\n♨️最近信号：{my_xh}\n')
            f.write(f'💰平均成本: {jj_jun_ben[code]}\n💤估值获取时间：{gz_time[0]}\n')
            f.write(f'💹估收益率: {now_syl:.2f}% | 最大回撤：{jj_max_hc:.2f}%\n')
            f.write(f'💹当日估值: {gz[0]:.2f} | 估算涨幅: {gzf[0]:.2f}%|🌉{okk}\n')
            f.write(f'📶MACD信号：{now_action}|{min_ok} \n☑️操作(bc{jj_max_hc / 3:.2f}%)：')
            print(f'{jj_max_hc / 3}')
            # 行情分析-------------------------------------------------------------------
            # 加判断-上次信号是死叉再卖
            if now_syl <= -(jj_max_hc / 3):
                if gzf[0] < -1:
                    f.write('补仓\n')
                else:
                    f.write('波动不大,先不动\n')
            elif now_syl > 0.6:
                if now_action == '💀死叉':
                    f.write('💀死叉直接清仓\n')
                elif now_action == '🐦‍🔥金叉' or my_xh[0] == '💰':
                    f.write('🐦‍🔥金叉进行中不操作\n')
                else:
                    f.write('清仓清仓\n')
            else:
                f.write('不用操作\n')
            init_all()
            print('===============================')
            f.write('==================================\n')


def to_rc():
    jj_code = jj_rc['基金代码'].values
    jj_name = jj_rc['基金名称'].values
    jj_type = jj_rc['板块'].values
    try:
        with open(f'分析log/{now_date}入场分析报告', 'w', encoding='utf-8') as f:
            for i in range(len(jj_code)):
                get_fund_data(jj_code[i])
                min5 = min(list_jz[:5])
                min20 = min(list_jz[:20])
                pass_ma5 = sum(list_jz[:5]) / 5
                pass_ma20 = sum(list_jz[:20]) / 20
                now_ma5 = (sum(list_jz[:4]) + gz[0]) / 5
                now_ma20 = (sum(list_jz[:19]) + gz[0]) / 20
                my_bz_c = math.sqrt(
                    sum((x - pass_ma20) ** 2 for x in list_jz[:20]))  # 计算20日标准差(波动率)
                upper_band = pass_ma20 + 2 * my_bz_c  # 布林带上轨 = 中轨 + 2倍标准差
                lower_band = pass_ma20 - 2 * my_bz_c  # 布林带下轨 = 中轨 - 2倍标准差
                print(f'正在分析{jj_name[i]}({jj_code[i]})')
                print(f'板块：{jj_type[i]}')
                a = get_near_xh(i, jj_rc)
                today = date.today()
                xh_time = datetime.strptime(a.split("(")[1].split(")")[0], "%Y-%m-%d").date()
                days = (today - xh_time).days
                print(a)
                if gz[0] < min5 and pass_ma5 > pass_ma20:
                    f.write(f'🔍{jj_name[i]}({jj_code[i]})\n')
                    f.write(f'🍞板块：{jj_type[i]}\n')
                    f.write(f'💹当日估值: {gz[0]:.2f} | 估算涨幅: {gzf[0]:.2f}%\n')
                    f.write("💰5日最低买入\n")
                    f.write('==================================\n')
                elif a[0] == '💰' and days < 10:
                    f.write(f'🔍{jj_name[i]}({jj_code[i]})\n')
                    f.write(f'🍞板块：{jj_type[i]}\n')
                    f.write(f'💹当日估值: {gz[0]:.2f} | 估算涨幅: {gzf[0]:.2f}%\n')
                    f.write(f"📶前{days}天出现金叉信号,看涨幅判断是否买入\n")
                    f.write('==================================\n')
                init_all()
    except Exception as ee:
        print('错了', ee)


if __name__ == '__main__':
    n = 0
    while 1:
        now_time = datetime.now().strftime('%H%M')
        print(f'当前时间：{now_time}')
        if n == 0 or now_time == '1430' or now_time == '1440' or now_time == '1445' or now_time == '1455':
            print('‍🐦‍🔥🐦‍🔥🐦‍🔥🐦‍🔥😎持有分析🐦‍🔥🐦‍🔥🐦‍🔥🐦‍🔥')
            to_cy()
            goto_email(f'分析log/{now_date}持仓分析报告', '5补持有分析')
            print('‍🐦‍🔥🐦‍🔥🐦‍🔥🐦‍🔥😎入场分析🐦‍🔥🐦‍🔥🐦‍🔥🐦‍🔥')
            to_rc()
            goto_email(f'分析log/{now_date}入场分析报告', '5补入场报告')
            n = n + 1
            if n == 5:
                print('运行结束')
                break
        sleep(2)
